use std::io;
use std::io::{BufReader, Read};

// use std::collections::HashMap;
// use std::fs::File;
// use std::io::{Seek, SeekFrom, Read, Write};
// use std::path::Path;
//
// pub struct StringFileWrapper {
//     file: File,
//     length: usize,
//     buffers: HashMap<usize, String>,
//     buffer_length: usize,
// }
//
// impl StringFileWrapper {
//     pub  fn new(file: File, chunk_length: usize) -> Self {
//         let buffer_length = if chunk_length < 2 { 1_000_000 } else { chunk_length };
//         StringFileWrapper {
//             file,
//             length: 0,
//             buffers: HashMap::new(),
//             buffer_length,
//         }
//     }
//
//     pub fn get_buffer(&mut self, index: usize) -> &str {
//         if !self.buffers.contains_key(&index) {
//             let mut buffer = vec![0; self.buffer_length];
//             self.file.seek(SeekFrom::Start((index * self.buffer_length) as u64)).unwrap();
//             let bytes_read = self.file.read(&mut buffer).unwrap();
//             let buffer_str = String::from_utf8_lossy(&buffer[..bytes_read]).into_owned();
//             self.buffers.insert(index, buffer_str);
//
//             // Save memory by keeping max 2MB buffer chunks and min 2 chunks
//             if self.buffers.len() > std::cmp::max(2, 2_000_000 / self.buffer_length) {
//                 let oldest_key = *self.buffers.keys().next().unwrap();
//                 if oldest_key != index {
//                     self.buffers.remove(&oldest_key);
//                 }
//             }
//         }
//         &self.buffers[&index]
//     }
//
//     pub fn len(&mut self) -> usize {
//         if self.length == 0 {
//             let current_position = self.file.seek(SeekFrom::Current(0)).unwrap();
//             self.length = self.file.seek(SeekFrom::End(0)).unwrap() as usize;
//             self.file.seek(SeekFrom::Start(current_position)).unwrap();
//         }
//         self.length
//     }
//
//     pub fn get(&mut self, index: usize) -> Option<char> {
//         let buffer_index = index / self.buffer_length;
//         let buffer = self.get_buffer(buffer_index);
//         buffer.chars().nth(index % self.buffer_length)
//     }
//
//     pub  fn get_slice(&mut self, start: usize, end: usize) -> String {
//         let buffer_start = start / self.buffer_length;
//         let buffer_end = end / self.buffer_length;
//
//         if buffer_start == buffer_end {
//             let buffer = self.get_buffer(buffer_start);
//             buffer[(start % self.buffer_length)..(end % self.buffer_length)].to_string()
//         } else {
//             let start_slice = self.get_buffer(buffer_start)[(start % self.buffer_length)..].to_string();
//             let end_slice = self.get_buffer(buffer_end)[..(end % self.buffer_length)].to_string();
//             let middle_slices: String = (buffer_start + 1..buffer_end)
//                 .map(|i| self.get_buffer(i).to_string())
//                 .collect();
//             start_slice + &middle_slices + &end_slice
//         }
//     }
//
//    pub  fn set(&mut self, index: usize, value: &str) {
//         let current_position = self.file.seek(SeekFrom::Current(0)).unwrap();
//         self.file.seek(SeekFrom::Start(index as u64)).unwrap();
//         self.file.write_all(value.as_bytes()).unwrap();
//         self.file.seek(SeekFrom::Start(current_position)).unwrap();
//     }
// }
//
// fn main() {
//     let file = File::open("example.txt").unwrap();
//     let mut wrapper = StringFileWrapper::new(file, 1_000_000);
//
//     println!("Length: {}", wrapper.len());
//     println!("Character at index 10: {:?}", wrapper.get(10));
//     println!("Slice from 10 to 20: {}", wrapper.get_slice(10, 20));
//
//     wrapper.set(10, "new_value");
// }
// 定义 StringFileWrapper，用于包装字符串或文件
pub struct StringFileWrapper {
    pub(crate) content: String,
    pub(crate) index: usize,
}

impl StringFileWrapper {
    pub  fn new<R: Read>(reader: R, chunk_length: usize) -> io::Result<Self> {
        let mut content = String::new();
        let mut buf_reader = BufReader::new(reader);
        buf_reader.read_to_string(&mut content)?;
        Ok(Self { content, index: 0 })
    }

    pub  fn read_char(&mut self) -> Option<char> {
        if self.index < self.content.len() {
            let ch = self.content.chars().nth(self.index)?;
            self.index += 1;
            Some(ch)
        } else {
            None
        }
    }

     pub fn peek_char(&self) -> Option<char> {
        self.content.chars().nth(self.index)
    }

    pub  fn len(&self) -> usize {
        self.content.len()
    }
}

